from django.db import transaction
from django.db.models import Sum
from rest_framework import serializers
from rest_framework.exceptions import ValidationError

from ERP_5.utils.get_inventory import get_inventory_by_goods
from purchase_info.models import PurchaseModel, PurchaseItemModel
from warehouse_info.models import PurchaseStorageItemModel


class PurchaseItemsSerializer(serializers.ModelSerializer):
    """
    采购单中的项目 的序列化器
    """

    model_number = serializers.CharField(source='goods.model_number', read_only=True)
    color = serializers.CharField(source='goods.color', read_only=True)
    nits_name = serializers.CharField(source='goods.units.basic_name', read_only=True)
    cur_inventory = serializers.SerializerMethodField(read_only=True)

    # 增加一个已经入库数量的序列化属性（未来在新增入库单的时候需要展示）
    already_in_number = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = PurchaseItemModel
        fields = '__all__'

    def get_cur_inventory(self, obj):
        return get_inventory_by_goods(obj.goods.id)

    def get_already_in_number(self, obj):
        # 先根据采购单ID作为一个过滤条件, 基于当前货品ID作为第二个过滤条件， 而且入库单的状态是已经审核
        in_count = PurchaseStorageItemModel.objects.filter(
            purchase_storage__purchase__id=obj.purchase.id,
            goods_id=obj.goods.id).exclude(purchase_storage__status='0')\
            .aggregate(sum=Sum('purchase_count'))
        if in_count:
            return in_count['sum'] if in_count['sum'] else 0
        return 0

class PurchaseSerializer(serializers.ModelSerializer):
    """
    采购单的序列化器
    """
    # 采购单列表中需要展示的商品信息：
    goods_info = serializers.SerializerMethodField(read_only=True)
    # item_list 用于新增，修改，查询
    item_list = PurchaseItemsSerializer(many=True)

    class Meta:
        model = PurchaseModel
        fields = '__all__'

    def create(self, validated_data):
        item_list = validated_data.pop('item_list')
        with transaction.atomic():
            purchase = PurchaseModel.objects.create(**validated_data)
            for item in item_list:
                PurchaseItemModel.objects.create(purchase=purchase, **item)
        return purchase

    # 同时插入采购单和采购单中货品项。必须重写update
    def update(self, instance, validated_data):
        if instance.status != '0':
            raise ValidationError("采购单已经生效，不能修改!")
        item_list = validated_data.pop('item_list')
        old_list = instance.item_list.all()
        with transaction.atomic():
            if old_list.exists():
                # 然后把旧数据删除，因为在validated_data拿不到货品库存数据的ID
                instance.item_list.all().delete()

            for item in item_list:  # 重新插入采购项 数据
                PurchaseItemModel.objects.create(purchase=instance, **item)
            result = super(PurchaseSerializer, self).update(instance=instance, validated_data=validated_data)
        return result

    def get_goods_info(self, obj):
        """
        商品信息是由： 商品1名称 商品1规格 , 商品2名称 商品2规格 ，....
        """
        if obj.item_list.all():
            result = []
            for item in obj.item_list.all():
                result.append(item.name + (item.specification if item.specification else ''))
            return ', '.join(result)
        return ""
